﻿// PMActiveXCtrl.cpp : CPMActiveXCtrl ActiveX 控件类的实现。

#include "stdafx.h"
#include "PMActiveX.h"
#include "PMActiveXCtrl.h"
#include "PMActiveXPropPage.h"
#include "afxdialogex.h"
#pragma comment(lib, "IPHLPAPI.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNCREATE(CPMActiveXCtrl, COleControl)

// 消息映射

BEGIN_MESSAGE_MAP(CPMActiveXCtrl, COleControl)
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()

// 调度映射

BEGIN_DISPATCH_MAP(CPMActiveXCtrl, COleControl)
	DISP_FUNCTION_ID(CPMActiveXCtrl, "GetMacAddress", dispidGetMacAddress, GetMacAddress, VT_BSTR, VTS_NONE)
END_DISPATCH_MAP()

// 事件映射

BEGIN_EVENT_MAP(CPMActiveXCtrl, COleControl)
END_EVENT_MAP()

// 属性页

// TODO: 根据需要添加更多属性页。请记住增加计数!
BEGIN_PROPPAGEIDS(CPMActiveXCtrl, 1)
	PROPPAGEID(CPMActiveXPropPage::guid)
END_PROPPAGEIDS(CPMActiveXCtrl)

// 初始化类工厂和 guid

IMPLEMENT_OLECREATE_EX(CPMActiveXCtrl, "MFCACTIVEXCONTRO.PMActiveXCtrl.1",
	0xb1573aca,0xa582,0x4268,0x85,0x09,0x0a,0x5c,0xc4,0xdf,0x66,0x5e)

// 键入库 ID 和版本

IMPLEMENT_OLETYPELIB(CPMActiveXCtrl, _tlid, _wVerMajor, _wVerMinor)

// 接口 ID

const IID IID_DPMActiveX = {0x250626e9,0x7378,0x40dc,{0x99,0xbe,0x20,0x49,0xc7,0x0e,0xdb,0xb4}};
const IID IID_DPMActiveXEvents = {0xe41ecb01,0x947c,0x4a1b,{0x81,0x60,0x62,0xcf,0x52,0x95,0x5b,0xa6}};

// 控件类型信息

static const DWORD _dwPMActiveXOleMisc =
	OLEMISC_SETCLIENTSITEFIRST |
	OLEMISC_INSIDEOUT |
	OLEMISC_CANTLINKINSIDE |
	OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CPMActiveXCtrl, IDS_PMACTIVEX, _dwPMActiveXOleMisc)

// CPMActiveXCtrl::CPMActiveXCtrlFactory::UpdateRegistry -
// 添加或移除 CPMActiveXCtrl 的系统注册表项

BOOL CPMActiveXCtrl::CPMActiveXCtrlFactory::UpdateRegistry(BOOL bRegister)
{
	// TODO:  验证您的控件是否符合单元模型线程处理规则。
	// 有关更多信息，请参考 MFC 技术说明 64。
	// 如果您的控件不符合单元模型规则，则
	// 必须修改如下代码，将第六个参数从
	// afxRegApartmentThreading 改为 0。

	if (bRegister)
		return AfxOleRegisterControlClass(
			AfxGetInstanceHandle(),
			m_clsid,
			m_lpszProgID,
			IDS_PMACTIVEX,
			IDB_PMACTIVEX,
			afxRegApartmentThreading,
			_dwPMActiveXOleMisc,
			_tlid,
			_wVerMajor,
			_wVerMinor);
	else
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}


// CPMActiveXCtrl::CPMActiveXCtrl - 构造函数

CPMActiveXCtrl::CPMActiveXCtrl()
{
	InitializeIIDs(&IID_DPMActiveX, &IID_DPMActiveXEvents);
	// TODO:  在此初始化控件的实例数据。
}

// CPMActiveXCtrl::~CPMActiveXCtrl - 析构函数

CPMActiveXCtrl::~CPMActiveXCtrl()
{
	// TODO:  在此清理控件的实例数据。
}

BSTR CPMActiveXCtrl::GetMacAddress()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	CString strResult;

	// TODO: 在此添加调度处理程序代码
	ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
	PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
	if (pAddresses == NULL)
	{
		return NULL;
	}

	if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
	{
		free(pAddresses);
		pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
		if (pAddresses == NULL)
		{
			return NULL;
		}
	}

	wchar_t acMAC[32] = { 0 };

	if (GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == NO_ERROR)
	{

		for (PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next)
		{
			// 确保 MAC 地址的长度为 00-00-00-00-00-00
			if (pCurrAddresses->PhysicalAddressLength != 6)
			{
				continue;
			}
			wsprintf((LPWSTR)acMAC, _T("%02X-%02X-%02X-%02X-%02X-%02X"),
				int(pCurrAddresses->PhysicalAddress[0]),
				int(pCurrAddresses->PhysicalAddress[1]),
				int(pCurrAddresses->PhysicalAddress[2]),
				int(pCurrAddresses->PhysicalAddress[3]),
				int(pCurrAddresses->PhysicalAddress[4]),
				int(pCurrAddresses->PhysicalAddress[5]));
			break;
		}
	}

	free(pAddresses);
	strResult = acMAC;

	return strResult.AllocSysString();
}

// CPMActiveXCtrl::OnDraw - 绘图函数

void CPMActiveXCtrl::OnDraw(
			CDC* pdc, const CRect& rcBounds, const CRect& /* rcInvalid */)
{
	if (!pdc)
		return;

	// TODO:  用您自己的绘图代码替换下面的代码。
	pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
	pdc->Ellipse(rcBounds);
}

// CPMActiveXCtrl::DoPropExchange - 持久性支持

void CPMActiveXCtrl::DoPropExchange(CPropExchange* pPX)
{
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
	COleControl::DoPropExchange(pPX);

	// TODO: 为每个持久的自定义属性调用 PX_ 函数。
}


// CPMActiveXCtrl::OnResetState - 将控件重置为默认状态

void CPMActiveXCtrl::OnResetState()
{
	COleControl::OnResetState();  // 重置 DoPropExchange 中找到的默认值

	// TODO:  在此重置任意其他控件状态。
}


// CPMActiveXCtrl 消息处理程序
